# !/usr/bin/env python
# encoding: utf-8


"""
  @author: gaogao
  @file: check_equip_comm_thread.py
  @time: 2022/7/31 17:04
  @desc:
"""
import random
from re import T
import pyvisa as visa
from PyQt5.QtCore import QObject, pyqtSignal, QThread
import time
from utils.log_util import loggings
from ATS.proberdriver.cascade_prober import CascadeProber
from ATS.util.calcu_step_util import get_step_list
from utils.read_ini_2_dict import get_refrence_data
from utils.get_wave_power_util import get_wave_power_value
from ATS.application.LASER_App.L8164B_App import L8164B_App
from ATS.application.LASER_App.N7744C_App import N7744C_App
from ATS.application.LASER_App.N7786C_App import N7786C_App


class RepeatabilityTask(QObject):
    result_signal = pyqtSignal(object, object)
    finished_signal = pyqtSignal()
    error_signal = pyqtSignal(object)

    def __init__(self, duration, frequency):
        super().__init__()
        self.duration = int(duration) * 60
        self.frequency = int(frequency)
        self.interval = int(self.duration / self.frequency)
        self.cp = CascadeProber("192.168.1.100")
        self.l8164_inst = L8164B_App("SS3")
        self.l8164_inst.set_wave_length(1330)
        self.l8164_inst.output_on()
        self.n7744_inst = N7744C_App("SS2")
        self.n7786_inst = N7786C_App("SS1")
        self.flag = True

    def run(self):
        try:
            self.chuck_oprtical_probe_contact()
            QThread.sleep(1)
            if self.interval > 0:
                for i in range(self.frequency):
                    if self.flag:
                        self.probe_area_scan()
                        self.steady_bias()
                        wave_list,gc_list = self.get_loss_gc_result()
                        self.result_signal.emit(wave_list,gc_list)
                        QThread.sleep(self.interval)
                    else:
                        break
                self.finished_signal.emit()
            else:
                wave_list,gc_list = self.get_loss_gc_result()
                self.result_signal.emit(wave_list,gc_list)
                self.finished_signal.emit()
        except Exception as e:
            loggings.error("RepeatabilityTask "+str(e))
            self.error_signal.emit(str(e))
        finally:
            self.chuck_oprtical_probe_separation()

    def get_loss_gc_result(self):
        self.n7744_inst.set_logging_state("STOP")
        if self.l8164_inst.get_sweep_status() == "+1":
            self.l8164_inst.stop_sweep()
        wave_list = get_step_list(1271, 1331, 1)
        points = len(wave_list)
        self.l8164_inst.set_power_unit()
        self.l8164_inst.set_power_value(10)
        time.sleep(2)
        p_in = self.l8164_inst.fetch_input_power()
        self.l8164_inst.set_sweep_mode()
        self.l8164_inst.query_sweep_pmax(1271, 1331)
        self.l8164_inst.set_repeat_mode()
        self.l8164_inst.set_wave_sweep_speed()
        self.l8164_inst.set_start_stop_step_wave(1271, 1331, 1)
        self.l8164_inst.trigger_config()
        self.l8164_inst.trigger_output()
        self.l8164_inst.trigger_input()
        self.l8164_inst.output_on()
        self.l8164_inst.set_wave_sweep_state()
        time.sleep(1)
        # n7744c_app.reset()
        self.n7744_inst.set_power_unit()
        self.n7744_inst.set_power_range(10)
        self.n7744_inst.set_auto_gain()
        self.n7744_inst.set_power_atim()
        self.n7744_inst.trigger_input_mode()
        self.n7744_inst.set_power_wave_length(1310)
        self.n7744_inst.set_logging_points(points)
        self.n7744_inst.set_logging_state()
        time.sleep(4)
        self.l8164_inst.trigger()
        time.sleep(1)
        while True:
            state = self.n7744_inst.get_func_state()
            if state == "LOGGING_STABILITY,COMPLETE":
                y_data = self.n7744_inst.get_func_res()
                break
        y_data = [float(i) for i in y_data]
        if self.l8164_inst.get_sweep_status() == "+1":
            self.l8164_inst.stop_sweep()

        wave_power_tuple = get_refrence_data()
        for wave_index in range(len(wave_list)):
            y_data[wave_index] = float(p_in) - y_data[wave_index] - get_wave_power_value(wave_list[wave_index],
                                                                                         wave_power_tuple)
        loss_gc_list = [float(i) / 2 for i in y_data]
        return wave_list, loss_gc_list

    def steady_bias(self):
        self.n7744_inst.set_logging_state("STOP")
        self.n7744_inst.reset()
        self.l8164_inst.set_wave_length(1310)
        self.l8164_inst.set_power_unit()
        self.l8164_inst.set_power_value(10)
        time.sleep(2)
        self.l8164_inst.output_on()

        self.n7744_inst.set_power_range(10)
        self.n7744_inst.set_auto_gain()
        self.n7744_inst.trigger_input_mode()
        self.n7744_inst.set_power_wave_length(1310)
        self.n7744_inst.set_logging_points()

        # init
        self.n7786_inst.reset()
        time.sleep(1)
        self.n7786_inst.set_stabilization_mode(0)
        self.n7786_inst.set_random_points_stepwidth()
        self.n7786_inst.set_trigger_conf_mode(4)
        self.n7786_inst.set_sample_point_rate()

        self.n7786_inst.set_wave_length(1310)
        self.n7786_inst.start_polarimeter_logging()
        self.n7786_inst.start_polarization_sequence()
        self.n7744_inst.set_logging_state("START")
        time.sleep(4)
        self.n7786_inst.trigger()
        while True:
            state = self.n7744_inst.get_func_state()
            if state == "LOGGING_STABILITY,COMPLETE":
                result_list = self.n7744_inst.get_func_res()
                break
        max_index = result_list.index(max(result_list))
        min_index = result_list.index(min(result_list))
        while True:
            log_value = self.n7786_inst.get_logged_value()
            if log_value == "+0":
                polarization_data = self.n7786_inst.get_polarization_sweep_data()
                break
        self.n7786_inst.stop_logging_polcontroller()
        state = self.n7786_inst.get_opc_state()
        if state == "1":
            self.n7786_inst.set_external_trigger_delay()
            self.n7786_inst.set_trigger_conf_mode()
            self.n7786_inst.set_stabilization_mode(1)

        max_polar = [polarization_data[max_index * 3], polarization_data[max_index * 3 + 1],
                     polarization_data[max_index * 3 + 2]]
        # print(max_polar)
        self.n7786_inst.set_polarization_value(*max_polar)
        self.n7744_inst.set_logging_state("STOP")

    def probe_area_scan(self):
        self.cp.area_scan()
        # self.cp.gradient_search()


    def chuck_oprtical_probe_contact(self):
        self.cp.move_chuck_contact()
        self.cp.move_optical_probe_height("H1")
        QThread.sleep(1)
        self.cp.move_optical_probe_height("H2")

    def chuck_oprtical_probe_separation(self):
        self.cp.move_chuck_separation()
        self.cp.move_optical_separation_height("H1")
        QThread.sleep(1)
        self.cp.move_optical_separation_height("H2")
